class Snake {
    element: HTMLElement; // 蛇容器
    head: HTMLElement; // 蛇头
    bodies: HTMLCollection; // 所有蛇的身体，包含蛇头
    constructor() {
        this.element = document.getElementById('snake')! // 蛇容器
        this.head = document.querySelector('#snake > div')! // 取蛇容器的第一个div
        this.bodies = this.element.getElementsByTagName('div') // 获取蛇身体
    }
    // 获取蛇头X坐标
    get X() {
        return this.head.offsetLeft
    }
    // 设置蛇头X坐标
    set X(value:number) {
        if (this.X === value) return
        if (value < 0 || value > 290) {
            throw new Error('蛇死了！')
        }


        this.moveBody() // 先移动身体再设置蛇头坐标，否则会导致身体位置错位
        this.head.style.left = value + 'px'

        this.checkHeadBody() // 检查是否撞到自己
        
    }
    // 获取蛇头Y坐标
    get Y() {
        return this.head.offsetTop
    }
    // 设置蛇头Y坐标
    set Y(value:number) {
        if (this.Y === value) return
        if (value < 0 || value > 290) {
            throw new Error('蛇死了！')
        }
        this.moveBody()
        this.head.style.top = value + 'px'

        this.checkHeadBody()// 检查是否撞到自己
    }
    // 蛇增加身体
    addBody() {
        this.element.insertAdjacentHTML('beforeend', '<div></div>')
    }

    // 蛇身体移动
    moveBody() {
        for (let i = this.bodies.length - 1; i > 0; i--) {

            // 获取前边身体位置
            let X = (this.bodies[i - 1] as HTMLElement).offsetLeft;
            let Y = (this.bodies[i - 1] as HTMLElement).offsetTop;

            // 当前身体位置移动到前一个身体位置
            (this.bodies[i] as HTMLElement).style.left = X + 'px';
            (this.bodies[i] as HTMLElement).style.top = Y + 'px';
        }
    }

    // 检查蛇头是否撞到身体。蛇头和任意身体重叠，表示撞到身体
    checkHeadBody() {
        for (let i = 1; i < this.bodies.length; i++) {
            let body = this.bodies[i] as HTMLElement
            let bodyX = body.offsetLeft
            let bodyY = body.offsetTop
            if (this.X === bodyX && this.Y === bodyY) {
                throw new Error('蛇撞到自己了！')
            }
        }
    }

    

}

export default Snake